package saxion.speelveld.spaceengineer.controller;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import saxion.speelveld.spaceengineer.model.Building;
import saxion.speelveld.spaceengineer.model.Game;
import saxion.speelveld.spaceengineer.model.ProducingBuilding;
import saxion.speelveld.spaceengineer.model.Resource;
import saxion.speelveld.spaceengineer.model.ResourceType;
import android.os.Handler;
import android.util.Log;

/**
 * 
 * @author Tom
 * 
 */

public class TimedEvents
{
	private static Timer mainTimer = null;

	private int GameTimeInTicks;

	private Game gameModel;

	// runs without timer be reposting self

	public TimedEvents(Game gameModel)
	{
		if (mainTimer == null)
		{
			Log.w("TimedEvents", "mainTimer is null");
			// random tijd voor de rampen.
			mainTimer = new Timer();
			this.gameModel = gameModel;
			gatherResourceEventHandler gatherResourcesTimer = new gatherResourceEventHandler();
			// lowerBuildTimeLeftOfBuildings lowerBuildTimeTimer = new lowerBuildTimeLeftOfBuildings();
			mainTimer.schedule(gatherResourcesTimer, 5000, 5000);
			// mainTimer.schedule(lowerBuildTimeTimer, 1000, 1000);
		}
		else
		{
			Log.w("TimedEvents", "mainTimer still active.. not null");
		}
	}

	Handler h2 = new Handler();

	Runnable run = new Runnable()
	{

		@Override
		public void run()
		{
			// TODO check for each building if it has produced and at it to stash of resources or something.

			if (gameModel == null)
			{
				return;
			}

			Log.i("TimedEvents", "word uitgevoerd :)");

			for (Resource resource : gameModel.getResourceArray())
			{
				resource.setAmountGainPerTick(0);
				resource.setAmountCostPerTick(0);
			}

			ArrayList<Building> buildings = gameModel.getBuildings();
			for (Building building : buildings)
			{
				if (building instanceof ProducingBuilding && building.isConnectedToSpaceCenter() == true)
				{
					ProducingBuilding pbTemp = (ProducingBuilding) building;

					boolean enoughResources = true;
					boolean maxStorageCap = false;

					for (Resource costRes : pbTemp.getResourceProducedCostsOverTime())
					{
						if (gameModel.getResourceAmount(costRes.getResourceType()) < costRes.getAmount())
						{
							enoughResources = false;
						}
					}

					for (Resource gainRes : pbTemp.getResourceProducedGainsOverTime())
					{
						if (gameModel.getResourceAmount(gainRes.getResourceType()) == gameModel
							.getResourceAmount(ResourceType.STORAGESPACE))
						{
							maxStorageCap = true;
						}
					}

					if (enoughResources == true && maxStorageCap == false)
					{
						for (Resource res : pbTemp.getResourceProducedGainsOverTime())
						{
							int extraResourceAmount = res.getAmount();
							ResourceType extraResourceType = res.getResourceType();
							gameModel.getResourceArray()[res.getResourceType().ordinal()]
								.addAmountGainPerTick(res.getAmount());
							gameModel.addResourceAmount(extraResourceType, extraResourceAmount);
						}
						for (Resource cost : pbTemp.getResourceProducedCostsOverTime())
						{
							int extraResourceAmount = cost.getAmount();
							ResourceType extraResourceType = cost.getResourceType();
							gameModel.getResourceArray()[cost.getResourceType().ordinal()]
								.addAmountCostPerTick(cost.getAmount());
							gameModel.substractResourceAmount(extraResourceType, extraResourceAmount);
						}
					}
				}
			}
			// population gedoe
			int popgain = (int) (Math.random() * 4 / 2);
			int actualgain = 0;
			if (gameModel.getResourceAmount(ResourceType.POPULATION) + popgain <= gameModel
				.getResourceAmount(ResourceType.POPULATIONCAP))
			{
				for (int x = 0; x <= popgain; x++)
				{
					if (Math.random() * 100 < gameModel.getResourceAmount(ResourceType.HAPPINESS))
					{
						actualgain++;
					}
				}
			}

			int jewelerydemand = (int) (Math.random() * 5 * gameModel.getResourceAmount(ResourceType.POPULATION));
			if (jewelerydemand > gameModel.getResourceAmount(ResourceType.JEWELRY))
			{
				jewelerydemand = gameModel.getResourceAmount(ResourceType.JEWELRY);
			}
			gameModel.substractResourceAmount(ResourceType.JEWELRY, jewelerydemand);
			gameModel.addResourceAmount(ResourceType.MONEY, 5 * jewelerydemand);
			gameModel.getResourceArray()[ResourceType.MONEY.ordinal()].setAmountGainPerTick(jewelerydemand * 5);
			gameModel.getResourceArray()[ResourceType.JEWELRY.ordinal()].setAmountCostPerTick(jewelerydemand);

			gameModel.forceUpdate(false);
			gameModel.tick();

			// Log.d("TimedEvents", "checked " + BuildingCount + " and " + ProducingBuildingCount
			// + " are able to produce goods :)");
		}
	};

	private class gatherResourceEventHandler extends TimerTask
	{
		public void run()
		{
			h2.post(run);
		}

	}

	/**
	 * 
	 * @author Tom This timertask checks lowers de builing time that is left and checks if they are done
	 */
	private class lowerBuildTimeLeftOfBuildings extends TimerTask
	{

		@Override
		public void run()
		{
			// TODO Voor elk gebouw dat gebouwd word de resterende bouwtijd veminderen
			// controleren of het gebouw af is.

			// 1: Get all buildings
			ArrayList<Building> buildings = gameModel.getBuildings();
			// 2: Check if resterende bouwtijd (>0)
			for (Building building : buildings)
			{
				if (building.getBuildTimeLeft() > 0)
				{
					// 3: verlaag bouwtijd.
					building.minusBuildTimeLeft(1);
					if (building.getBuildTimeLeft() == 0)
					{
						// TODO achievement: if building time = 0: building achievements checken :)
						// Show custom popup message ;)!
					}
				}

			}

		}

	}

	private class Disaster extends TimerTask
	{

		@Override
		public void run()
		{

		}

	}

	public static void StopTimer()
	{
		if (mainTimer != null)
		{
			mainTimer.cancel();
			mainTimer = null;
		}
	}

	public static void RestartTimer(Game gameModel)
	{
		new TimedEvents(gameModel);
	}
}
